package inet.sms.process;

import inet.db.common.DBException;
import inet.pdu.SMSRequest;
import inet.pdu.SMSResponse;
import inet.util.DBProcess;
import inet.util.DateTime;
import inet.util.Logger;
import inet.util.Queue;
import inet.util.StringTool;
import inet.util.testString;

import java.io.PrintStream;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Vector;

import red.sms.db.dao.SmsMoDAO;

public class RequestProcessor extends Thread {
	private Logger logger;
	private SMSRequest request;
	private Queue requestQueue;
	private SMSResponse response;
	private Queue responseQueue;
	private Vector checkQueue;
	private Queue responseQueue1;
	private int timeCheckLoop = 5;

	public RequestProcessor() {
		this.logger = null;
		this.requestQueue = null;
		this.responseQueue = null;
		this.request = null;
		this.response = null;
		this.requestQueue = Server.getRequestQueue();
		this.responseQueue = Server.getResponseQueue();
		this.logger = new Logger(super.getClass().getName());
		this.checkQueue = new Vector();
	}

	private void processReceiveInfo(SMSRequest request) throws DBException {
		// Su ly tin nhan nhan duoc o day
		boolean foo = false;
		String smsInfo = request.getInfo();
		String maDichVu = getDichVu(smsInfo);
		maDichVu = maDichVu.toUpperCase();
		String sdt = request.getSenderNumber();
		String dauSo = request.getServiceNumber();
		// luu DB
		// DBProcess db=new DBProcess();
		// BigDecimal requestId=db.saveMO(dauSo,sdt,smsInfo);
		// request.setRequestId(requestId);
		if (!(maDichVu.equals("CTS") || (maDichVu.equals("HT")))) {
			// luu tin nhan ko dung vao file
			String content = "From: " + sdt + "      Sai ma dich vu: "
					+ maDichVu + "     on: " + getTimeNow();
			String fileLog = "fail_";
			this.logger.log(content, fileLog);
		}

		else {
			String content = "From: " + sdt + "      To: " + dauSo
					+ "     on: " + getTimeNow() + "     Info: " + smsInfo;
			String fileLog = "sending_";
			this.logger.log(content, fileLog);
			// this.response.setInfo("Gui OTP thanh cong");
		}

		String info = null;
		try {
			info = request.getInfo().toUpperCase();
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		String code = null;
		for (int i = 0; i < ServiceConfig.codesList.size(); i++) {
			code = (String) ServiceConfig.codesList.get(i);
			if (!info.startsWith(code))
				continue;
			request.setCommandCode(code);
			if (info.length() <= code.length())
				break;
			char ch = request.getInfo().charAt(code.length());
			if (((ch < '0') || (ch > '9')) && ((ch < 'a') || (ch > 'z'))
					&& ((ch < 'A') || (ch > 'Z')))
				break;
			request.setInfo(StringTool.appendString(request.getInfo(),
					code.length(), " "));
			this.logger.log("   UpdatedTo: " + request.getInfo());

			break;
		}

		Queue requestQueue = (Queue) ServiceConfig.codesTable.get(request
				.getCommandCode());
		if (requestQueue != null) {
			requestQueue.enqueue(request);
		} else {
			this.response = request.getResponse();
			this.response.setContentType(0);
			this.response.setCommandCode("INV");
			this.response.setMessageType(21);
			this.response.setInfo(HelpConfig.lookupHelp(this.response
					.getServiceNumber()));
			this.responseQueue.enqueue(this.response);
		}

	}
	
	private void enqueueMO(SMSRequest request) throws DBException{
		        // processing SMS request
				String smsInfo = request.getInfo();
				String maDichVu = getDichVu(smsInfo);
				maDichVu = maDichVu.toUpperCase();
				String sdt = request.getSenderNumber();
				String dauSo = request.getServiceNumber();
				// STEP1: SAVING TO DATABASE
				SmsMoDAO.enqueue(request);
				
				//STEP2: LOG TO FILE, AND RETURN
				if (!(maDichVu.equals("CTS") || (maDichVu.equals("HT")))) {
					// luu tin nhan ko dung vao file
					String content = "From: " + sdt + "      Sai ma dich vu: "
							+ maDichVu + "     on: " + getTimeNow();
					String fileLog = "fail_";
					this.logger.log(content, fileLog);
				}

				else {
					String content = "From: " + sdt + "      To: " + dauSo
							+ "     on: " + getTimeNow() + "     Info: " + smsInfo;
					String fileLog = "sending_";
					this.logger.log(content, fileLog);
				}

	}
	
	public boolean checkRequest(SMSRequest request) {
		try {
			boolean rs = true;

			if ((this.checkQueue == null) || (this.checkQueue.size() == 0)) {
				this.checkQueue.add(request);
				return true;
			}
			Vector tempQueue = new Vector();

			DateTime time = new DateTime();

			for (int i = 0; i < this.checkQueue.size(); ++i) {
				SMSRequest temp = (SMSRequest) this.checkQueue.get(i);
				DateTime timeOfRq = DateTime
						.getInstance(temp.getTimeReceived());
				if ((request.getSenderNumber().equals(temp.getSenderNumber()))
						&& (request.getServiceNumber().equals(temp
								.getServiceNumber()))) {
					int t = (time.getHour() - timeOfRq.getHour()) * 360
							+ (time.getMinute() - timeOfRq.getMinute()) * 60
							+ time.getSecond() - timeOfRq.getSecond();

					if ((((t < 0) || (t >= this.timeCheckLoop)))
							&& (((t >= 0) || (t <= this.timeCheckLoop)))) {
						continue;
					}
					rs = false;
				} else {
					int t = (time.getHour() - timeOfRq.getHour()) * 360
							+ (time.getMinute() - timeOfRq.getMinute()) * 60
							+ time.getSecond() - timeOfRq.getSecond();

					if ((((t < 0) || (t >= this.timeCheckLoop)))
							&& (((t >= 0) || (t <= this.timeCheckLoop))))
						continue;
					tempQueue.add(temp);
				}

			}

			tempQueue.add(request);
			this.checkQueue = tempQueue;
			this.logger.log("MO check=>" + this.checkQueue.size());

			return rs;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}

	public static void main1(String[] args) {
		RequestProcessor main = new RequestProcessor();

		SMSRequest rq = new SMSRequest();
		rq.setServiceNumber("7042");
		rq.setSenderNumber("84902264213");
		rq.setTimeReceived(DateTime.getInstance().getTimestamp());
		System.out.println("0:t:" + main.checkRequest(rq));
		SMSRequest rq1 = new SMSRequest();
		rq1.setServiceNumber("7042");
		rq1.setSenderNumber("84902264213");
		rq1.setTimeReceived(DateTime.getInstance().getTimestamp());
		System.out.println("1:t:" + main.checkRequest(rq1));
		SMSRequest rq2 = new SMSRequest();
		rq2.setServiceNumber("7042");
		rq2.setSenderNumber("84902264213");
		rq2.setTimeReceived(DateTime.getInstance().getTimestamp());
		System.out.println("2:f:" + main.checkRequest(rq2));

		SMSRequest rq3 = new SMSRequest();
		rq3.setServiceNumber("7042");
		rq3.setSenderNumber("84902264213");
		rq3.setTimeReceived(DateTime.getInstance().getTimestamp());
		System.out.println("3:f:" + main.checkRequest(rq3));

		SMSRequest rq4 = new SMSRequest();
		rq4.setServiceNumber("7042");
		rq4.setSenderNumber("84902264213");
		rq4.setTimeReceived(DateTime.getInstance().getTimestamp());
		System.out.println("4:f:" + main.checkRequest(rq4));
		try {
			sleep(5000L);
		} catch (Exception e) {
			e.printStackTrace();
		}
		SMSRequest rq5 = new SMSRequest();
		rq5.setServiceNumber("7042");
		rq5.setSenderNumber("84915343006");
		rq5.setTimeReceived(DateTime.getInstance().getTimestamp());
		System.out.println("5:t:" + main.checkRequest(rq5));
	}

	/*
	 * (non-Javadoc) Module su ly luu DB tai day
	 */

	public void run() {
		while (Server.isRunning()) {
			this.request = ((SMSRequest) this.requestQueue.dequeue());
			if (this.request == null) {
				continue;
			}

			if (!Logger.isVerbose()) {
				System.out.println("==> " + this.request.getSenderNumber()
						+ " --> " + this.request.getServiceNumber() + ": "
						+ this.request.getInfo() + ":"
						+ this.request.getTimeReceived().toString());
			}
			try

			{
				enqueueMO(this.request);
				//processReceiveInfo(this.request);
				// new ResponseProcessor().start();

			} catch (Exception ex) {
				this.logger.error("run: " + ex.getMessage() + "\n");
			}
		}
	}

	public int getTimeCheckLoop() {
		return this.timeCheckLoop;
	}

	public void setTimeCheckLoop(int timeCheckLoop) {
		this.timeCheckLoop = timeCheckLoop;
	}

	public static String getDichVu(String text) {
		String maDichVu = text.split(" ")[0];
		return maDichVu;
	}

	public static String getTimeNow() {
		String s;
		Format formatter;
		Date date = new Date();

		formatter = new SimpleDateFormat("hh:mm:ss");
		s = formatter.format(date);
		return s;
	}

	public void sendOneWaySMS(SMSResponse smsResponse) {
		// this.responseQueue = Server.getResponseQueue();
		this.responseQueue1 = new inet.util.Queue();
		this.responseQueue1.enqueue(smsResponse);
		return;
	}

	public static void main(String args[]) {
		/*RequestProcessor mainProcessor = new RequestProcessor();
		SMSResponse smsResponse = new SMSResponse();
		smsResponse.setCommandCode("HT");
		smsResponse.setInfo("One way SMS");
		smsResponse.setReceiverNumber("841685458982");
		// smsResponse.setSenderNumber("7045");
		smsResponse.setServiceNumber("7045");
		smsResponse.setMobileOperator("NOT.SET");
		smsResponse.setMessageType(0);
		smsResponse.setContentType(0);
		// smsResponse.set
		// setId(new BigDecimal(0.0D));
		smsResponse.setRequestId(new BigDecimal(0.0D));
		Queue responseQueue1 = new inet.util.Queue();
		responseQueue1.enqueue(smsResponse);
		// mainProcessor.sendOneWaySMS(smsResponse);
*/
		RequestProcessor test = new RequestProcessor();
		SMSRequest srequest = new SMSRequest();
		srequest.setRequestId(new BigDecimal(123));
		srequest.setCommandCode("HT");
		srequest.setInfo("test");
		srequest.setReceiverNumber("092022");
		srequest.setServiceNumber("7045");
		try {
			test.enqueueMO(srequest);
		} catch (DBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

/*
 * request.setCommandCode("TEST"); request.setId(new BigDecimal(0.0D));
 * request.setRequestId(new BigDecimal(0.0D));
 * request.setMobileOperator("NOT.SET"); this.sFrom =
 * getParam("Sender Number: ", this.sFrom); this.sTo =
 * getParam("Service Number: ", this.sTo); this.sInfo = getParam("Info: ", "");
 * if ((this.sFrom.length() <= 1) || (this.sTo.length() <= 1) ||
 * (this.sInfo.length() <= 1)) return; request.setSenderNumber(this.sFrom);
 * request.setServiceNumber(this.sTo);
 */

